home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / thesrc10.zip / NONANSI.C < prev    next >
C/C++ Source or Header  |  1992-08-12  |  17KB  |  553 lines

  1. /***********************************************************************/
  2. /* NONANSI.C -                                                         */
  3. /* This file contains all calls to non-ansi conforming routines.       */
  4. /***********************************************************************/
  5. /*
  6.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  7.  * Copyright (C) 1991,1992 Mark Hessling
  8.  *
  9.  * This program is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU General Public License as
  11.  * published by the Free Software Foundation; either version 2 of
  12.  * the License, or any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17.  * General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to:
  21.  *
  22.  *    The Free Software Foundation, Inc.
  23.  *    675 Mass Ave,
  24.  *    Cambridge, MA 02139 USA.
  25.  *
  26.  *
  27.  * If you make modifications to this software that you feel increases
  28.  * it usefulness for the rest of the community, please email the
  29.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  30.  * This software is going to be maintained and enhanced as deemed
  31.  * necessary by the community.
  32.  *
  33.  * Mark Hessling                     email: M.Hessling@itc.gu.edu.au
  34.  * 36 David Road                     Phone: +61 7 849 7731
  35.  * Holland Park                      Fax:   +61 7 875 7877
  36.  * QLD 4121
  37.  * Australia
  38.  */
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41.  
  42. #include "the.h"
  43.  
  44. #ifdef UNIX
  45. #include <pwd.h>
  46. #endif
  47.  
  48. /*#define DEBUG 1*/
  49.  
  50. #ifdef DOS
  51. #include <dos.h>
  52. #include <bios.h>
  53. union REGS regs;
  54. #endif
  55.  
  56. /*-------------------------- external data ----------------------------*/
  57. extern unsigned char curr_path[MAX_FILE_NAME+1] ;
  58. extern unsigned char sp_path[MAX_FILE_NAME+1] ;
  59. extern unsigned char sp_fname[MAX_FILE_NAME+1] ;
  60. extern unsigned char dir_path[MAX_FILE_NAME+1] ;   /* for dir and ls commands */
  61. extern char file_disposition;
  62. extern struct stat stat_buf;
  63. /*---------------------- function definitions -------------------------*/
  64. #ifdef DOS
  65. char get_mode(void);
  66. #endif
  67. /***********************************************************************/
  68. #ifdef PROTO
  69. int file_readable(char *filename)
  70. #else
  71. int file_readable(filename)
  72. char *filename;
  73. #endif
  74. /***********************************************************************/
  75. {
  76. /*--------------------------- local data ------------------------------*/
  77. /*--------------------------- processing ------------------------------*/
  78. #ifdef TRACE
  79.  trace_function("nonansi.c :file_readable");
  80. #endif
  81.  if (!file_exists(filename))
  82.    {
  83. #ifdef TRACE
  84.     trace_return();
  85. #endif
  86.     return(YES);
  87.    }
  88.  if (access(filename,R_OK) == (-1))
  89.    {
  90. #ifdef TRACE
  91.     trace_return();
  92. #endif
  93.     return(NO);
  94.    }
  95. #ifdef TRACE
  96.     trace_return();
  97. #endif
  98.  return(YES);
  99. }
  100. /***********************************************************************/
  101. #ifdef PROTO
  102. int file_writable(char *filename)
  103. #else
  104. int file_writable(filename)
  105. char *filename;
  106. #endif
  107. /***********************************************************************/
  108. {
  109. /*--------------------------- local data ------------------------------*/
  110. /*--------------------------- processing ------------------------------*/
  111. #ifdef TRACE
  112.  trace_function("nonansi.c :file_writable");
  113. #endif
  114.  if (!file_exists(filename))
  115.    {
  116. #ifdef TRACE
  117.     trace_return();
  118. #endif
  119.     return(YES);
  120.    }
  121.  if (access(filename,W_OK) == (-1))
  122.    {
  123. #ifdef TRACE
  124.     trace_return();
  125. #endif
  126.     return(NO);
  127.    }
  128. #ifdef TRACE
  129.  trace_return();
  130. #endif
  131.  return(YES);
  132. }
  133. /***********************************************************************/
  134. #ifdef PROTO
  135. int file_exists(char *filename)
  136. #else
  137. int file_exists(filename)
  138. char *filename;
  139. #endif
  140. /***********************************************************************/
  141. {
  142. /*--------------------------- local data ------------------------------*/
  143. /*--------------------------- processing ------------------------------*/
  144. #ifdef TRACE
  145.  trace_function("nonansi.c :file_exists");
  146. #endif
  147.  if (access(filename,F_OK) == (-1))
  148.    {
  149. #ifdef TRACE
  150.     trace_return();
  151. #endif
  152.     return(NO);
  153.    }
  154. #ifdef TRACE
  155.  trace_return();
  156. #endif
  157.  return(YES);
  158. }
  159. /***********************************************************************/
  160. #ifdef PROTO
  161. int remove_file(char *filename)
  162. #else
  163. int remove_file(filename)
  164. char *filename;
  165. #endif
  166. /***********************************************************************/
  167. {
  168. /*--------------------------- local data ------------------------------*/
  169. /*--------------------------- processing ------------------------------*/
  170. #ifdef TRACE
  171.  trace_function("nonansi.c :remove_file");
  172. #endif
  173. #ifdef VMS
  174.  if (delete(filename) == (-1))
  175. #else
  176.  if (unlink(filename) == (-1))
  177. #endif
  178.    {
  179. #ifdef TRACE
  180.     trace_return();
  181. #endif
  182.     return(ERROR);
  183.    }
  184. #ifdef TRACE
  185.  trace_return();
  186. #endif
  187.  return(OK);
  188. }
  189. /***********************************************************************/
  190. #ifdef PROTO
  191. short splitpath(unsigned char *filename)
  192. #else
  193. short splitpath(filename)
  194. unsigned char *filename;
  195. #endif
  196. /***********************************************************************/
  197. {
  198. /*--------------------------- local data ------------------------------*/
  199.  short len;
  200.  char work_filename[MAX_FILE_NAME+1] ;
  201. #if defined(DOS) || defined(OS2)
  202.  int new_dos_disk=0,current_dos_disk=0;        /* 1 - A,2 - B... */
  203.  int temp_disk=0;
  204. #ifdef OS2
  205.  ULONG logical_os2_drives=0L;
  206. #endif
  207. #endif
  208. /*--------------------------- processing ------------------------------*/
  209. #ifdef TRACE
  210.  trace_function("nonansi.c :splitpath");
  211. #endif
  212.  strcpy(sp_path,"");
  213.  strcpy(sp_fname,"");
  214.  strcpy(work_filename,filename);
  215. /*---------------------------------------------------------------------*/
  216. /* If the supplied filename is empty, set the path = cwd and filename  */
  217. /* equal to blank.                                                     */
  218. /*---------------------------------------------------------------------*/
  219.  if (strcmp(filename,"") == 0)
  220.    {
  221.     getcwd(sp_path,MAX_FILE_NAME);
  222.     strcpy(sp_fname,"");
  223.    }
  224. /*---------------------------------------------------------------------*/
  225. /* For DOS, get current drive and determine if the filename contains a */
  226. /* disk drive specification.                                           */
  227. /*---------------------------------------------------------------------*/
  228. #ifdef DOS
  229.  new_dos_disk = 0;       /* by default, no drive specified in filename */
  230. #ifdef TC
  231.  current_dos_disk = getdisk() + 1;
  232. #else
  233.  _dos_getdrive(¤t_dos_disk);
  234. #endif
  235. #endif
  236.  
  237. #ifdef OS2
  238.  new_dos_disk = 0;       /* by default, no drive specified in filename */
  239.  DosQCurDisk(¤t_dos_disk,&logical_os2_drives);
  240. #endif
  241.  
  242. #if defined(DOS) || defined(OS2)
  243.  if (*(filename+1) == ':')/* we assume this means a drive secification */
  244.    {
  245.     new_dos_disk = (toupper(*(filename)) - 'A') + 1;
  246.     strcpy(work_filename,(filename+2));
  247.    }
  248. #endif
  249.  
  250. /*---------------------------------------------------------------------*/
  251. /* Check if the first character is tilde; translate HOME env variable  */
  252. /* if there is one. Obviously only applicable to UNIX.                 */
  253. /*---------------------------------------------------------------------*/
  254. #ifdef UNIX
  255.  if (*(work_filename) == '~')
  256.    {
  257.     if (*(work_filename+1) == SLASH)
  258.       {
  259.        strcpy(work_filename,(unsigned char *)getenv("HOME"));
  260.        strcat(work_filename,(filename+1));
  261.       }
  262.     else
  263.       {
  264.        struct passwd *pwd;
  265.  
  266.        strcpy(sp_path,filename+1);
  267.        if ((len = strzeq(sp_path,SLASH)) != (-1))
  268.           sp_path[len] = '\0';
  269.        if ((pwd = getpwnam(sp_path)) == NULL)
  270.           return(ERROR);
  271.        strcpy(work_filename,pwd->pw_dir);
  272.        if (len != (-1))
  273.           strcat(work_filename,(filename+1+len));
  274.       }
  275.    }
  276. #endif
  277. /*---------------------------------------------------------------------*/
  278. /* For DOS, check if the a disk was specified, and if so change to the */
  279. /* specified drive.                                                    */
  280. /*---------------------------------------------------------------------*/
  281. #if defined(DOS) || defined(OS2)
  282.  if (new_dos_disk != 0
  283.  &&  new_dos_disk != current_dos_disk)
  284.    {
  285. #ifdef DOS
  286. #ifdef TC
  287.     setdisk((int)(new_dos_disk-1));
  288.     temp_disk = getdisk()+1;
  289. #else
  290.     _dos_setdrive(new_dos_disk,&temp_disk);
  291.     _dos_getdrive(&temp_disk);
  292. #endif
  293. #endif
  294.  
  295. #ifdef OS2
  296.     DosSelectDisk(new_dos_disk);
  297.     DosQCurDisk(&temp_disk,&logical_os2_drives);
  298. #endif
  299.     if (temp_disk != new_dos_disk)  /* invalid drive */
  300.       {
  301. #ifdef TRACE
  302.        trace_return();
  303. #endif
  304.        return (ERROR);
  305.       }
  306.    }
  307. #endif
  308. /*---------------------------------------------------------------------*/
  309. /* First determine if the supplied filename is a directory.            */
  310. /*---------------------------------------------------------------------*/
  311.  if ((stat(work_filename,&stat_buf) == 0)
  312.  &&  (stat_buf.st_mode & S_IFMT) == S_IFDIR)
  313.    {
  314.     strcpy(sp_path,work_filename);
  315.     strcpy(sp_fname,"");
  316.    }
  317.  else          /* here if the file doesn't exist or is not a directory */
  318.    {
  319.     len = strzreveq(work_filename,SLASH);
  320.     switch(len)
  321.       {
  322.        case (-1):
  323.             getcwd(sp_path,MAX_FILE_NAME);
  324.             strcpy(sp_fname,work_filename);
  325.             break;
  326.        case 0:
  327.             strcpy(sp_path,work_filename);
  328.             sp_path[1] = '\0';
  329.             strcpy(sp_fname,work_filename+1+len);
  330.             break;
  331.       default:
  332.             strcpy(sp_path,work_filename);
  333.             sp_path[len] = '\0';
  334.             strcpy(sp_fname,work_filename+1+len);
  335.             break;
  336.      }
  337.    }
  338. /*---------------------------------------------------------------------*/
  339. /* Remove any trailing slash from the path, except if it root dir      */
  340. /* or for DOS and OS/2 looks like C:\                                  */
  341. /*---------------------------------------------------------------------*/
  342. #ifndef VMS
  343. #if defined(DOS) || defined(OS2)
  344.  len = strlen(sp_path);
  345.  if (sp_path[len-1] == SLASH)
  346.    {
  347.     if ((strcmp(STR_SLASH,sp_path) == 0)
  348.     ||  (sp_path[1] == ':' && sp_path[2] == SLASH && len == 3))
  349.        ;
  350.     else
  351.        sp_path[len-1] = '\0';
  352.    }
  353. #else
  354.  len = strlen(sp_path);
  355.  if (strcmp(STR_SLASH,sp_path) != 0)
  356.     if (sp_path[len-1] == SLASH)
  357.        sp_path[len-1] = '\0';
  358. #endif
  359. #endif
  360. /*---------------------------------------------------------------------*/
  361. /* For DOS or OS/2 save the current directory of the new disk.         */
  362. /*---------------------------------------------------------------------*/
  363. #if defined(DOS) || defined(OS2)
  364.  if (new_dos_disk != 0
  365.  &&  new_dos_disk != current_dos_disk)
  366.     getcwd(work_filename,MAX_FILE_NAME);
  367. #endif
  368. /*---------------------------------------------------------------------*/
  369. /* Change directory to the supplied path, if possible and store the    */
  370. /* expanded path.                                                      */
  371. /*---------------------------------------------------------------------*/
  372.  if (chdir(sp_path) != 0)
  373.    {
  374. #ifdef TRACE
  375.     trace_return();
  376. #endif
  377.     return(ERROR);
  378.    }
  379.  getcwd(sp_path,MAX_FILE_NAME);
  380. /*---------------------------------------------------------------------*/
  381. /* For DOS or OS/2, change back to the current directory of the now    */
  382. /* current disk and then change back to the current disk.              */
  383. /*---------------------------------------------------------------------*/
  384. #if defined(DOS) || defined(OS2)
  385.  if (new_dos_disk != 0
  386.  &&  new_dos_disk != current_dos_disk)
  387.    {
  388.     if (chdir(work_filename) != 0)
  389.       {
  390. #ifdef TRACE
  391.        trace_return();
  392. #endif
  393.        return(ERROR);
  394.       }
  395. #ifdef DOS
  396. #ifdef TC
  397.     setdisk((int)(current_dos_disk-1));
  398. #else
  399.     _dos_setdrive(current_dos_disk,&temp_disk);
  400. #endif
  401. #endif
  402. #ifdef OS2
  403.     DosSelectDisk(current_dos_disk);
  404. #endif
  405.    }
  406. #endif
  407.  
  408.  chdir(curr_path);
  409. /*---------------------------------------------------------------------*/
  410. /* Append the OS directory character to the path if it doesn't already */
  411. /* end in the character.                                               */
  412. /*---------------------------------------------------------------------*/
  413. #ifndef VMS
  414.  len = strlen(sp_path);
  415.  if (len > 0)
  416.     if (sp_path[len-1] != SLASH)
  417.        strcat(sp_path,(unsigned char *)STR_SLASH);
  418. #endif
  419. #ifdef TRACE
  420.  trace_return();
  421. #endif
  422.  return(OK);
  423. }
  424. #ifdef NO_RENAME
  425. /***********************************************************************/
  426. int rename(path1,path2)
  427. char *path1;
  428. char *path2;
  429. /***********************************************************************/
  430. /* Function  : Emulate missing rename() function from SystemV          */
  431. /* Parameters: path1    - old filename                                 */
  432. /*             path2    - new_filename                                 */
  433. /* Return    : 0 on success, -1 on error                               */
  434. /***********************************************************************/
  435. {
  436. #ifdef TRACE
  437.  trace_function("nonansi.c :rename");
  438. #endif
  439.   if (link(path1,path2) != 0)
  440.     {
  441. #ifdef TRACE
  442.      trace_return();
  443. #endif
  444.      return(-1);
  445.     }
  446.   if (unlink(path1) != 0)
  447.     {
  448. #ifdef TRACE
  449.      trace_return();
  450. #endif
  451.      return(-1);
  452.     }
  453. #ifdef TRACE
  454.  trace_return();
  455. #endif
  456.  return(0);
  457. }
  458. #endif
  459. #ifdef DOS
  460. /***********************************************************************/
  461. void csr_size(start,end)
  462. /***********************************************************************/
  463. /* Function  : BIOS call to set size of cursor                         */
  464. /* Parameters: start    - starting row                                 */
  465. /*             end      - ending row                                   */
  466. /* Return    : void                                                    */
  467. /***********************************************************************/
  468. register int  start;
  469. register int  end;
  470. {
  471. #ifdef TRACE
  472.  trace_function("nonansi.c :csr_size");
  473. #endif
  474.   regs.h.ah = 1;
  475.   regs.h.ch = start;
  476.   regs.h.cl = end;
  477.   int86(0x10,®s,®s);
  478. #ifdef TRACE
  479.  trace_return();
  480. #endif
  481.  return;
  482. }
  483. /***********************************************************************/
  484. char get_mode(void)
  485. /***********************************************************************/
  486. /* Function  : BIOS call to get current video mode.                    */
  487. /* Parameters: n/a                                                     */
  488. /* Return    : mode number                                             */
  489. /***********************************************************************/
  490. {
  491. #ifdef TRACE
  492.  trace_function("nonansi.c :get_mode");
  493. #endif
  494.  regs.h.ah = 15;
  495.  int86(0x10,®s,®s);
  496.  regs.h.ah = 0;
  497. #ifdef TRACE
  498.  trace_return();
  499. #endif
  500.  return(regs.h.al);
  501. }
  502. #endif
  503. #ifdef OS2
  504. /***********************************************************************/
  505. #ifdef PROTO
  506. bool FATFileSystem(char *fname)
  507. #else
  508. bool FATFileSystem(fname)
  509. char *fname;
  510. #endif
  511. /***********************************************************************/
  512. {
  513. typedef struct _FSNAME {
  514.         USHORT cbName;
  515.         UCHAR  szName[1];
  516. } FSNAME;
  517. typedef struct _FSQINFO {
  518.         USHORT iType;
  519.         FSNAME Name;
  520.         UCHAR  rgFSAData[59];
  521. } FSQINFO;
  522. typedef FSQINFO FAR *PFSQINFO;
  523. /*--------------------------- local data ------------------------------*/
  524.  USHORT nDrive,cbData;
  525.  ULONG lMap;
  526.  FSQINFO bData;
  527.  BYTE bName[3];
  528.  FSNAME *pFSName;
  529. /*--------------------------- processing ------------------------------*/
  530. #ifdef TRACE
  531.  trace_function("file.c:    FATFileSystem");
  532. #endif
  533. /*---------------------------------------------------------------------*/
  534. /* This determines if the file system for the current path is FAT or   */
  535. /* not (usually HPFS).                                                 */
  536. /*---------------------------------------------------------------------*/
  537.  if ((strlen(fname) > 0) && fname[1] == ':')
  538.     bName[0] = fname[0];
  539.  else
  540.    {
  541.     DosQCurDisk(&nDrive, &lMap);
  542.     bName[0] = (char)(nDrive + '@');
  543.    }
  544.  bName[1] = ':';
  545.  bName[2] = 0;
  546.  cbData = sizeof(bData);
  547.  DosQFSAttach((PSZ)bName,0,1,(PBYTE)&bData,&cbData,0L);
  548.  pFSName = &bData.Name;
  549.  (char *)pFSName += pFSName->cbName + sizeof(pFSName->cbName)+1;
  550.  return(strcmp((char *)&(pFSName->szName[0]),"FAT") == 0);
  551. }
  552. #endif
  553.